package cloud.topdaddy.admin.system.controller;

import cloud.topdaddy.base.common.resp.PageResult;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.stp.StpUtil;
import cloud.topdaddy.admin.system.entity.SysUser;
import cloud.topdaddy.admin.system.entity.SysUserRole;
import cloud.topdaddy.admin.system.service.SysUserService;
import cloud.topdaddy.admin.system.service.SysUserRoleService;
import cloud.topdaddy.base.common.resp.R;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Caching;
import org.springframework.web.bind.annotation.*;
import lombok.extern.slf4j.Slf4j;
import java.util.List;

@RestController
@RequestMapping("/user")
@Slf4j
public class SysUserController {

    @Resource
    private SysUserService sysUserService;

    @Resource
    private SysUserRoleService sysUserRoleService;

    @GetMapping("/me")
    @SaCheckLogin
    public R<SysUser> me() {
        Long userId = StpUtil.getLoginIdAsLong();
        SysUser user = sysUserService.getById(userId);
        if (user != null) {
            user.setPassword(null);
        }
        return R.ok(user);
    }

    @GetMapping("/list")
    @SaCheckLogin
    @SaCheckPermission("system:user:list")
    public R<PageResult<SysUser>> list(SysUser sysUser,
                                  @RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
                                  @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
        try {
            Page<SysUser> page = new Page<>(pageNo, pageSize);
            
            // 使用QueryWrapper而不是LambdaQueryWrapper来避免版本兼容问题
            com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<SysUser> wrapper = 
                new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<>();
            
            // 添加默认排序，避免数据库查询不稳定
            wrapper.orderByDesc("create_time");
            
            if (StringUtils.isNotBlank(sysUser.getUsername())) {
                wrapper.like("username", sysUser.getUsername());
            }
            if (StringUtils.isNotBlank(sysUser.getPhone())) {
                wrapper.like("phone", sysUser.getPhone());
            }
            if (sysUser.getLockFlag() != null) {
                wrapper.eq("lock_flag", sysUser.getLockFlag());
            }
            
            // 过滤已删除的用户
            wrapper.eq("is_deleted", false);
            
            IPage<SysUser> result = sysUserService.page(page, wrapper);
            result.getRecords().forEach(u -> u.setPassword(null));
            
            // 转换为前端期望的PageResult格式
            PageResult<SysUser> pageResult =
                new PageResult<>();
            pageResult.setItems(result.getRecords());
            pageResult.setTotal(result.getTotal());
            pageResult.setPageNum(result.getCurrent());
            pageResult.setPageSize(result.getSize());
            pageResult.setPages(result.getPages());
            
            return R.ok(pageResult);
        } catch (Exception e) {
            log.error("查询用户列表失败", e);
            return R.serverError("查询用户列表失败: " + e.getMessage());
        }
    }

    @GetMapping("/{userId}")
    @SaCheckLogin
    public R<SysUser> get(@PathVariable("userId") Long userId) {
        try {
            SysUser user = sysUserService.getById(userId);
            if (user != null && !Boolean.TRUE.equals(user.getIsDeleted())) {
                user.setPassword(null);
                return R.ok(user);
            }
            return R.userErrorParam("用户不存在");
        } catch (Exception e) {
            log.error("获取用户信息失败, userId: {}", userId, e);
            return R.serverError("获取用户信息失败: " + e.getMessage());
        }
    }

    @PostMapping("/add")
    @SaCheckLogin
    @SaCheckPermission("system:user:add")
    public R<String> add(@RequestBody @Valid SysUser user) {
        try {
            // 检查用户名是否已存在
            com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<SysUser> checkWrapper = 
                new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<>();
            checkWrapper.eq("username", user.getUsername())
                       .eq("is_deleted", false);
            long count = sysUserService.count(checkWrapper);
            if (count > 0) {
                return R.userErrorParam("用户名已存在");
            }
            
            // 设置默认值
            if (user.getLockFlag() == null) {
                user.setLockFlag(false);
            }
            if (user.getIsDeleted() == null) {
                user.setIsDeleted(false);
            }
            
            // 处理密码
            if (StringUtils.isBlank(user.getPassword())) {
                user.setPassword(new BCryptPasswordEncoder().encode("123456")); // 默认密码
            } else if (!(user.getPassword().startsWith("$2a$") || user.getPassword().startsWith("$2b$") || user.getPassword().startsWith("$2y$"))) {
                user.setPassword(new BCryptPasswordEncoder().encode(user.getPassword()));
            }
            
            sysUserService.save(user);
            return R.ok("新增成功");
        } catch (Exception e) {
            log.error("新增用户失败", e);
            return R.serverError("新增用户失败: " + e.getMessage());
        }
    }

    @PutMapping("/update")
    @SaCheckLogin
    @SaCheckPermission("system:user:update")
    public R<String> update(@RequestBody @Valid SysUser user) {
        try {
            if (user.getUserId() == null) {
                return R.userErrorParam("用户ID不能为空");
            }
            
            // 检查用户是否存在
            SysUser existUser = sysUserService.getById(user.getUserId());
            if (existUser == null || Boolean.TRUE.equals(existUser.getIsDeleted())) {
                return R.userErrorParam("用户不存在");
            }
            
            // 检查用户名是否被其他用户占用
            if (StringUtils.isNotBlank(user.getUsername()) && !user.getUsername().equals(existUser.getUsername())) {
                com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<SysUser> checkWrapper = 
                    new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<>();
                checkWrapper.eq("username", user.getUsername())
                           .ne("user_id", user.getUserId())
                           .eq("is_deleted", false);
                long count = sysUserService.count(checkWrapper);
                if (count > 0) {
                    return R.userErrorParam("用户名已被占用");
                }
            }
            
            // 处理密码
            if (StringUtils.isNotBlank(user.getPassword())
                    && !(user.getPassword().startsWith("$2a$") || user.getPassword().startsWith("$2b$") || user.getPassword().startsWith("$2y$"))) {
                user.setPassword(new BCryptPasswordEncoder().encode(user.getPassword()));
            } else if (StringUtils.isBlank(user.getPassword())) {
                // 如果密码为空，不更新密码字段
                user.setPassword(null);
            }
            
            sysUserService.updateById(user);
            return R.ok("更新成功");
        } catch (Exception e) {
            log.error("更新用户失败, userId: {}", user.getUserId(), e);
            return R.serverError("更新用户失败: " + e.getMessage());
        }
    }

    @DeleteMapping("/delete/{userId}")
    @SaCheckLogin
    @SaCheckPermission("system:user:delete")
    public R<String> delete(@PathVariable("userId") Long userId) {
        try {
            // 检查用户是否存在
            SysUser user = sysUserService.getById(userId);
            if (user == null || Boolean.TRUE.equals(user.getIsDeleted())) {
                return R.userErrorParam("用户不存在");
            }
            
            // 不能删除自己
            Long currentUserId = StpUtil.getLoginIdAsLong();
            if (userId.equals(currentUserId)) {
                return R.userErrorParam("不能删除自己");
            }
            
            // 逻辑删除
            user.setIsDeleted(true);
            sysUserService.updateById(user);
            
            return R.ok("删除成功");
        } catch (Exception e) {
            log.error("删除用户失败, userId: {}", userId, e);
            return R.serverError("删除用户失败: " + e.getMessage());
        }
    }

    @PostMapping("/{userId}/roles")
    @SaCheckLogin
    @SaCheckPermission("system:user:assign-role")
    @Caching(evict = {
        @CacheEvict(cacheNames = "auth:roles#10m", key = "#userId"),
        @CacheEvict(cacheNames = "auth:perms#10m", key = "#userId"),
        @CacheEvict(cacheNames = "auth:myMenus#5m", key = "#userId"),
        @CacheEvict(cacheNames = "auth:myPerms#5m", key = "#userId")
    })
    public R<String> assignRoles(@PathVariable("userId") Long userId, @RequestBody List<Long> roleIdList) {
        try {
            // 检查用户是否存在
            SysUser user = sysUserService.getById(userId);
            if (user == null || Boolean.TRUE.equals(user.getIsDeleted())) {
                return R.userErrorParam("用户不存在");
            }
            
            // 清空旧关系
            com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<SysUserRole> deleteWrapper = 
                new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<>();
            deleteWrapper.eq("user_id", userId);
            sysUserRoleService.remove(deleteWrapper);
            
            // 新建关系
            if (roleIdList != null && !roleIdList.isEmpty()) {
                List<SysUserRole> batch = roleIdList.stream().map(rid -> {
                    SysUserRole ur = new SysUserRole();
                    ur.setUserId(userId);
                    ur.setRoleId(rid);
                    return ur;
                }).toList();
                sysUserRoleService.saveBatch(batch);
            }
            return R.ok("分配成功");
        } catch (Exception e) {
            log.error("分配角色失败, userId: {}, roleIdList: {}", userId, roleIdList, e);
            return R.serverError("分配角色失败: " + e.getMessage());
        }
    }

    @PostMapping("/{userId}/resetPassword")
    @SaCheckLogin
    @SaCheckPermission("system:user:reset-password")
    public R<String> resetPassword(@PathVariable("userId") Long userId) {
        try {
            SysUser user = sysUserService.getById(userId);
            if (user == null || Boolean.TRUE.equals(user.getIsDeleted())) {
                return R.userErrorParam("用户不存在");
            }
            
            user.setPassword(new BCryptPasswordEncoder().encode("123456"));
            sysUserService.updateById(user);
            return R.ok("重置成功，新密码为：123456");
        } catch (Exception e) {
            log.error("重置密码失败, userId: {}", userId, e);
            return R.serverError("重置密码失败: " + e.getMessage());
        }
    }

    public static class ChangePwdReq {
        public String oldPassword;
        public String newPassword;
        public String getOldPassword() { return oldPassword; }
        public void setOldPassword(String oldPassword) { this.oldPassword = oldPassword; }
        public String getNewPassword() { return newPassword; }
        public void setNewPassword(String newPassword) { this.newPassword = newPassword; }
    }

    @PutMapping("/changePassword")
    @SaCheckLogin
    public R<String> changePassword(@RequestBody ChangePwdReq req) {
        Long uid = StpUtil.getLoginIdAsLong();
        SysUser user = sysUserService.getById(uid);
        if (user == null) return R.userErrorParam("用户不存在");
        String stored = user.getPassword();
        if (stored != null && (stored.startsWith("$2a$") || stored.startsWith("$2b$") || stored.startsWith("$2y$"))) {
            if (req.oldPassword == null || !new BCryptPasswordEncoder().matches(req.oldPassword, stored)) {
                return R.userErrorParam("原密码不正确");
            }
        } else {
            if (req.oldPassword == null || !req.oldPassword.equals(stored)) {
                return R.userErrorParam("原密码不正确");
            }
        }
        if (StringUtils.isBlank(req.newPassword)) {
            return R.userErrorParam("新密码不能为空");
        }
        user.setPassword(new BCryptPasswordEncoder().encode(req.newPassword));
        sysUserService.updateById(user);
        return R.ok("修改成功");
    }
}
